package com.zimmur.app.mocolink.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.zimmur.app.mocolink.dao.OrderDetailMapper;
import com.zimmur.app.mocolink.dao.OrderExpressMapper;
import com.zimmur.app.mocolink.dao.OrderMapper;
import com.zimmur.app.mocolink.dao.ShoppingCartMapper;
import com.zimmur.app.mocolink.domain.common.Constant;
import com.zimmur.app.mocolink.domain.form.ShipOrderForm;
import com.zimmur.app.mocolink.domain.form.UserMoneyForm;
import com.zimmur.app.mocolink.domain.model.AppUser;
import com.zimmur.app.mocolink.domain.model.Order;
import com.zimmur.app.mocolink.domain.model.OrderDetail;
import com.zimmur.app.mocolink.domain.model.OrderDetailExample;
import com.zimmur.app.mocolink.domain.model.OrderExpress;
import com.zimmur.app.mocolink.domain.model.UserAddress;
import com.zimmur.app.mocolink.domain.param.OrderParam;
import com.zimmur.app.mocolink.domain.param.OrderParamForManage;
import com.zimmur.app.mocolink.domain.util.AppModuleEnum;
import com.zimmur.app.mocolink.domain.util.DateUtils;
import com.zimmur.app.mocolink.domain.util.IDWorkFactory;
import com.zimmur.app.mocolink.domain.util.PageUtil;
import com.zimmur.app.mocolink.domain.vo.AppUserInfo;
import com.zimmur.app.mocolink.domain.vo.OrderInfo;
import com.zimmur.app.mocolink.domain.vo.OrderVo;
import com.zimmur.app.mocolink.domain.vo.OrderVoForManage;
import com.zimmur.app.mocolink.domain.vo.ShoppingCartInfo;
import com.zimmur.app.mocolink.domain.vo.ShoppingCartVo;
import com.zimmur.app.mocolink.service.IAppUserService;
import com.zimmur.app.mocolink.service.IGoodsService;
import com.zimmur.app.mocolink.service.IOrderService;
import com.zimmur.app.mocolink.service.IShoppingCartService;

@Service
public class OrderServiceImpl implements IOrderService {
 
	@Autowired
	private OrderMapper orderMapper;
	@Autowired
	private OrderDetailMapper orderDetailMapper;
	@Autowired
	private OrderExpressMapper orderExpressMapper;
	@Autowired
	private IShoppingCartService shoppingCartService;
	@Autowired
	private IAppUserService appUserService;
	@Autowired
	private IGoodsService goodsService;
	
	@Override
	public OrderDetail selectDetailById(Integer orderDetailId) {
		return orderDetailMapper.selectByPrimaryKey(orderDetailId);
	}

	@Override
	public int commentOrderDetail(OrderDetail orderDetail) {
		int flag = orderDetailMapper.updateByPrimaryKeySelective(orderDetail);
		if(flag>0){
			OrderDetailExample example = new OrderDetailExample();
			example.createCriteria().andOrderIdEqualTo(orderDetail.getOrderId()).andIsCommentEqualTo(Constant.byte_0);
			int count = orderDetailMapper.countByExample(example);
			if(count==0){
				orderMapper.updateOrderStatus(orderDetail.getOrderId(), Constant.Order_Status_Done, Constant.Order_Status_Done_Text);
			}
		}
		//查询订单未评价明细，若无则更新订单状态
		return flag;
	}
	@Transactional
	@Override
	public int addOrder(UserAddress userAddress, String[] cartIds, Integer userId,String remark) {
		
		List<ShoppingCartVo> cartVos = shoppingCartService.selectByCartIds(cartIds);
		AppUserInfo appUserInfo= appUserService.selectInfoByUserId(userId);
		List<Integer> goodsIdList=new ArrayList<>();
		if(cartVos!=null && appUserInfo!=null ){
			Integer discount = appUserInfo.getDiscount()==null?100:appUserInfo.getDiscount();
			Order order = new Order();
			OrderExpress orderExpress = new OrderExpress();
			List<OrderDetail> details = new ArrayList<>();
			Double orderJe = 0D;
			Date nowTime = DateUtils.getNow();
			int goodsNum=0;
			String orderNo ="O"+IDWorkFactory.getID(AppModuleEnum.UserOrder);
			for(ShoppingCartVo cartVo:cartVos){
				goodsIdList.add(cartVo.getGoodsId());
				for(ShoppingCartInfo cartInfo:cartVo.getDetailList()){
					//验证库存
					if(cartInfo.getStockQuantity()<cartInfo.getQuantity()){
						return -2;
					}
					int quantity = cartInfo.getQuantity();
					if(quantity>0){
						OrderDetail detail = new OrderDetail();
						detail.setColorName(cartInfo.getColorName());
						detail.setCoverImg(cartVo.getCoverImage());
						detail.setCreateDate(nowTime);
						detail.setGoodsId(cartVo.getGoodsId());
						detail.setGoodsItemId(cartInfo.getGoodsItemId());
						detail.setGoodsName(cartVo.getGoodsName());
						detail.setIsComment(Constant.byte_0);
						detail.setQuantity(quantity);
						detail.setRefundQuantity(0);
						detail.setSizeName(cartInfo.getSizeName());
						detail.setSkuCode(cartInfo.getSkuCode());
						detail.setStyleCode(cartVo.getStyleCode());
						double price = cartInfo.getPrice().doubleValue();
						double buyPrcie = (price*discount)/100.00;
						double detailJe = buyPrcie*quantity;
						detail.setPrice(cartInfo.getPrice());
						detail.setBuyPrice(new BigDecimal(buyPrcie));
						detail.setDetailJe(new BigDecimal(detailJe));
						details.add(detail);
						
						orderJe+=price*quantity;
						goodsNum+=quantity;
					}
				}
			}
			if(details.size()==0){
				return -3;
			}
			Double discountJe = (100-discount) * orderJe/100.00;
			order.setCreateDate(nowTime);
			order.setDiscount(discount);
			order.setDiscountJe(new BigDecimal(discountJe));
			order.setGoodsNum(goodsNum);
			order.setOrderJe(new BigDecimal(orderJe));
			order.setTotalJe(new BigDecimal(orderJe-discountJe));
			order.setOrderNo(orderNo);
			order.setRemark(remark);
			order.setStatus(Constant.Order_Status_Wait_Pay);
			order.setStatusName(Constant.Order_Status_Wait_Pay_Text);
			order.setUserId(userId);
			order.setPayJe(new BigDecimal(0));
			
			
			orderExpress.setAddressee(userAddress.getContacts());
			orderExpress.setShipMobile(userAddress.getMobileNo());
			orderExpress.setShipProvince(userAddress.getProvince());
			orderExpress.setShipCity(userAddress.getCity());
			orderExpress.setShipArea(userAddress.getDistrict());
			orderExpress.setShipStreet(userAddress.getAddress());
			orderExpress.setUpdateTime(nowTime);
			int flag = orderMapper.insertSelective(order);
			if(flag > 0 ){
				int orderId = order.getId();
				orderExpress.setOrderId(orderId);
				orderExpressMapper.insertSelective(orderExpress);
				for(OrderDetail detail:details){
					detail.setOrderId(orderId);
				}
				goodsService.updateStockQuantity(details,Constant.Goods_Stocked_Buy);
				orderDetailMapper.batchInset(details);
				//删除购物车
				shoppingCartService.deleteCartByGoodsId(goodsIdList, userId);
			}
			return flag;
		
		}
		return -1;
	}

	@Override
	public Order selectByOrderId(Integer orderId) {
		return orderMapper.selectByPrimaryKey(orderId);	
	}

	@Override
	public int updateOrder(Order order) {
		return orderMapper.updateByPrimaryKeySelective(order);
	}

	@Override
	public PageUtil<OrderVo> selectByParam(OrderParam param) {
		PageUtil<OrderVo> page = new PageUtil<>();
		List<OrderVo> list = orderMapper.selectByParam(param);
		int count = orderMapper.countByParam(param);
		page.setPageNo(param.getPageNo());
		page.setPageSize(param.getPageSize());
		page.setItemList(list);
		page.setTotalRecord(count);
		return page;
	}

	@Override
	public PageUtil<OrderInfo> selectByParam(OrderParamForManage param) {
		PageUtil<OrderInfo> page = new PageUtil<>();
		List<OrderInfo> list = orderMapper.selectByParamForManage(param);
		int count = orderMapper.countbyParamForManage(param);
		page.setPageNo(param.getPageNo());
		page.setPageSize(param.getPageSize());
		page.setItemList(list);
		page.setTotalRecord(count);
		return page;
	}
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	@Override
	public synchronized int payOrder(Integer orderId, String adminName) {
		Order order = orderMapper.selectByPrimaryKey(orderId);
		if(order == null || order.getTotalJe()==null){
			return -1;
		}
		if(!Constant.Order_Status_Wait_Pay.equals(order.getStatus())){
			return -2;
		}
		BigDecimal payJe = order.getTotalJe();
		UserMoneyForm form = new UserMoneyForm();
		form.setAdminName(adminName);
		form.setAppUserId(order.getUserId());
		form.setDataId(orderId);
		form.setMoney(payJe.doubleValue());
		form.setType(Constant.User_Money_Pay);
		form.setSerialNumber(order.getOrderNo());
		
		int flag = appUserService.updateMoney(form);
		if(flag>0){
			order.setPayJe(payJe);
			order.setPayDate(DateUtils.getNow());
			order.setStatus(Constant.Order_Status_Wait_Send);
			order.setStatusName(Constant.Order_Status_Wait_Send_Text);
			flag = orderMapper.updateByPrimaryKeySelective(order);
			if(flag>0){
				List<OrderDetail> list = orderDetailMapper.selectByOrderId(orderId);
				goodsService.updateStockQuantity(list, Constant.Goods_Stocked_Pay);
			}
		}else if(flag==-1){
			return -1;
		}else if(flag == -2){
			return -3;
		}
		return flag;
	}

	@Override
	public OrderVoForManage selectOrderDetail(Integer orderId) {
		Order order = orderMapper.selectByPrimaryKey(orderId);
		if(order != null){
			List<OrderDetail> details = orderDetailMapper.selectByOrderId(orderId);
			OrderExpress orderExpress = orderExpressMapper.selectByOrderId(orderId);
			AppUserInfo appUserInfo = appUserService.selectInfoByUserId(order.getUserId());
			OrderVoForManage orderVo = new OrderVoForManage(order, details, orderExpress, appUserInfo);
			return orderVo;
		}
		return null;
	}
	@Transactional
	@Override
	public int saveShipInfo(ShipOrderForm form) {
		Order order = orderMapper.selectByPrimaryKey(form.getOrderId());
		OrderExpress orderExpress = orderExpressMapper.selectByOrderId(form.getOrderId());
		if(order == null || orderExpress == null){
			return -1;
		}
		if(!Constant.Order_Status_Wait_Send.equals(order.getStatus())){
			return -2;
		}
		order.setStatus(Constant.Order_Status_Wait_Sign);
		order.setStatusName(Constant.Order_Status_Wait_Sign_Text);
		
		orderExpress.setShipCompany(form.getCompanyName());
		orderExpress.setShipNo(form.getShipNo());
		orderExpress.setShipDate(DateUtils.dateFormat(form.getShipDate()+" 00:00:00"));
		orderExpress.setUpdateTime(DateUtils.getNow());
		int flag = orderExpressMapper.updateByPrimaryKeySelective(orderExpress);
		if(flag>0){
			orderMapper.updateByPrimaryKeySelective(order);
		}
		return flag;
	}

	@Override
	public int updateOrderStatus(Integer orderId, String status) {
		Order order = orderMapper.selectByPrimaryKey(orderId);
		int flag = 0;
		if(order == null){
			return -1;
		}
		if(Constant.Order_Status_Cancel.equals(status) && Constant.Order_Status_Wait_Pay.equals(order.getStatus())){
			order.setStatus(Constant.Order_Status_Cancel);
			order.setStatusName(Constant.Order_Status_Cancel_Text);
			flag = orderMapper.updateByPrimaryKeySelective(order);
			if(flag>0){
				List<OrderDetail> details = orderDetailMapper.selectByOrderId(orderId);
				goodsService.updateStockQuantity(details, Constant.Goods_Stocked_Cancel);
			}
		}
		if(Constant.Order_Status_Error.equals(status)){
			order.setStatus(Constant.Order_Status_Error);
			order.setStatusName(Constant.Order_Status_Error_Text);
			flag = orderMapper.updateByPrimaryKeySelective(order);
		}
		return flag;
	}

	
}
